<template>
	<div class="style-split-yd-table">
		<tool-bar v-if="tableConfig.toolBar" :tool-bar="tableConfig.toolBar" :single="single" :multiple="multiple"></tool-bar>
		<el-table
			ref="tableRef"
			v-loading="renderTableConfig.loading"
			:data="localData || renderTableData"
			:stripe="!renderTableConfig.noStripe"
			style="width: 100%"
			:height="renderTableConfig.height"
			:show-header="showHeader"
			@row-click="rowClickHandler"
			@sort-change="sortChangeHandler"
			@expand-change="expandChangeHandler"
			@selection-change="selectionChangeHandler"
		>
			<!-- 可展开列 -->
			<el-table-column v-if="renderTableConfig.expand" type="expand">
				<template #default="slotProps">
					<div class="expand-table-box">
						<slot name="expand" :data="slotProps.row"></slot>
					</div>
				</template>
			</el-table-column>
			<!-- 隐藏可展开列 -->
			<el-table-column v-if="renderTableConfig.expandHide" class="expand-hide" type="expand" width="1" show-overflow-tooltip>
				<template #default="slotProps">
					<div style="border: 1px solid #56698d">
						<slot name="expand" :data="slotProps.row"></slot>
					</div>
				</template>
			</el-table-column>
			<!-- 单选框列 -->
			<el-table-column v-if="renderTableConfig.enableRadio" label="" width="55" align="left">
				<template #default="slotProps">
					<el-radio-group v-model="renderTableConfig.radioId">
						<el-radio :label="slotProps.row.id">{{}}</el-radio>
					</el-radio-group>
				</template>
			</el-table-column>
			<!-- 复选框列 -->
			<el-table-column v-if="renderTableConfig.enableSelection" type="selection" width="55" align="left"> </el-table-column>
			<!-- 序号列 -->
			<el-table-column
				v-if="!renderTableConfig.disableOrderNumber"
				type="index"
				label="序号"
				width="55"
				align="center"
				:fixed="renderTableConfig.indexColumnFixed"
			>
				<template #default="scope">
					<span>{{ getIndex(renderTableConfig.pagination, scope.$index) }}</span>
				</template>
			</el-table-column>
			<!-- 数据列 -->
			<el-table-column
				v-for="(column, ind) in showColumn"
				:key="ind + 'column'"
				v-bind="column"
				:align="column.align ? column.align : 'left'"
				:sortable="column.sortable ? 'custom' : false"
				:fixed="column.fixed"
				show-overflow-tooltip
			>
				<template #default="slotProps">
					<div v-if="column.operation">
						<el-link
							v-for="(opera, index) in column.operation"
							v-show="opera.isShow === undefined ? true : opera.isShow(slotProps)"
							:key="index"
							style="margin-left: 6px; text-decoration: underline"
							:underline="false"
							@click.stop="opera.handler && opera.handler(slotProps)"
						>
							<span
								class="table-operation-text"
								:style="{ color: opera.color }"
								v-text="opera.text ? opera.text + '>' : slotProps.row[opera.rowKey as string]"
							></span>
						</el-link>
					</div>
					<div v-else>
						<div v-if="validatenull(slotProps.row[column.prop]) && !column.render && !column.renderXss">
							<span>-</span>
						</div>
						<div v-else>
							<div v-if="column.formatter">
								<span v-text="column.formatter(slotProps.row, slotProps.row[column.prop])"></span>
							</div>
							<div v-else-if="column.render">
								<RenderDom :v-node="column.render(slotProps.row, slotProps.row[column.prop])"></RenderDom>
							</div>
							<div v-else-if="column.renderXss">
								<RenderDom
									:v-node="column.renderXss(htmlEncodeByRegExpRowHandle(slotProps.row, column.prop), slotProps.row[column.prop])"
								></RenderDom>
							</div>
							<div v-else>
								<span>{{ slotProps.row[column.prop] }}</span>
							</div>
						</div>
					</div>
				</template>
			</el-table-column>

			<template #empty> <svg-icon class-name="nodata" icon-class="nodata"></svg-icon> {{ renderTableConfig.noDataText || '暂无数据~' }} </template>
		</el-table>
		<!-- 分页 -->
		<div class="pagination-box">
			<el-pagination
				v-if="renderTableConfig.pagination"
				v-model:current-page="renderTableConfig.pagination.pageNum"
				v-model:page-size="renderTableConfig.pagination.pageSize"
				class="yd-pagination"
				layout="total, sizes, prev, pager, next, jumper"
				:page-sizes="[10, 20, 30, 50, 100]"
				:total="totalCompute"
				@size-change="sizeChangeHandler"
				@current-change="currentChangeHandler"
			>
			</el-pagination>
		</div>
	</div>
</template>

<script setup name="YdTable" lang="tsx">
import { onMounted, ref, watch, computed, nextTick } from 'vue';
import RenderDom from './render';
import { htmlEncodeByRegExpRow } from '@/utils/common';
import ToolBar from './tableToolBar.vue';
import useCurrentInstance from '@/utils/useCurrentInstance';
import { ElTable } from 'element-plus';
import { validatenull } from '@/utils/validate';

/**
 * @props
 * */

export interface Props {
	formData: FormModelType;
	tableConfig: TableConfigType;
	tableData: TableOptionType[];
}
const props = withDefaults(defineProps<Props>(), {
	formData: () => {
		return {};
	},
	tableData: () => {
		return [];
	},
});

/**
 * @emit
 * */

const $emit = defineEmits<{
	(e: 'sizeChangeHandler'): void;
	(e: 'currentChangeHandler'): void;
	(e: 'sortChangeHandler'): void;
	(e: 'expandRowHandler', row: TableOptionType): void;
	(e: 'contractRowHandler', row: TableOptionType): void;
	(e: 'selectionChangeHandler', selectList: Array<TableOptionType>): void;
	(e: 'rowClickHandler', row: TableOptionType): void;
}>();

// const { proxy } = getCurrentInstance();
const { proxy } = useCurrentInstance();
/**
 * @data
 * */

const tableRef = ref<typeof ElTable>();

const renderTableConfig = computed(() => {
	return props.tableConfig;
});

const renderTableData = computed(() => {
	return props.tableData;
});

const totalCompute = computed(() => {
	let n;
	if (localTotal.value) {
		n = Number(localTotal.value);
	} else {
		n = Number(renderTableConfig.value.pagination?.total);
	}
	return Number.isNaN(n) ? 0 : n;
});

const showHeader = computed(() => {
	if (renderTableConfig.value.showHeader === false) {
		return false;
	}
	return true;
});

// 表单,用于修改分页数据
const formSubmitData = ref(props.formData);

// 用于修改按钮，选中长度不等于1禁用
let single = ref(true);
// 用于删除按钮，没有选中项禁用
let multiple = ref(true);
// 列表数据
let localData = ref(undefined);
// 总数
let localTotal = ref(0);
// 表单对象副本
let cloneFormData = ref<FormModelType>({});
// 是否第一次加载
let firstLoad = ref(true);
// // 排序默认字段及升降序
// const defaultSort = ref({
// 	prop: props.formData.orderByColumn,
// 	order: props.formData.isAsc,
// });
// // 上一次的升降序
let lastOrder = ref(props.formData.isAsc);

// 真正显示的数据列
// const showColumn = ref<TableConfigType[]>([]);

/**
 * @computed
 */

const showColumn = computed(() => {
	return renderTableConfig.value.columns.filter((item) => item.hide !== true);
});

// 默认排序
const defaultSortParam = computed(() => {
	let order = '';
	// 默认降序
	if (formSubmitData.value.isAsc === 'asc') {
		order = 'ascending';
	} else {
		order = 'descending';
	}
	return {
		prop: formSubmitData.value.orderByColumn || '',
		order: order,
	};
});

/**
 * @watch
 */
watch(
	() => props.tableData,
	() => {
		if (firstLoad.value) {
			cloneFormData.value = JSON.parse(JSON.stringify(props.formData));
			firstLoad.value = false;
			return;
		}
		cloneFormData.value = JSON.parse(JSON.stringify(props.formData));
		localData.value = undefined;
	},
	{ deep: true }
);

// 自定义列功能
watch(
	() => renderTableConfig.value.pagination as object,
	() => {
		// showColumn.value = val.columns.filter((item) => item.hide !== true);
		// 监听配置的pagination，更新表单的分页数据
		if (renderTableConfig.value.pagination) {
			changePagination();
		}
	},
	{ deep: true, immediate: true }
);

/**
 * @生命周期
 */
onMounted(() => {
	// 校验相关必传参数是否有传递
	// setTimeout(() => {
	// 	console.log('showColumn', showColumn);
	// 	console.log('renderTableData', renderTableData);
	// }, 2000);
});

/**
 * @方法
 *
 */

// 修改表单的分页信息
function changePagination() {
	const pagination = renderTableConfig.value.pagination;
	if (pagination) {
		formSubmitData.value.pageSize = pagination.pageSize || 10; //默认10
		formSubmitData.value.pageNum = pagination.pageNum;
		if (pagination.isAsc) formSubmitData.value.isAsc = pagination.isAsc;
		if (pagination.orderByColumn) formSubmitData.value.orderByColumn = pagination.orderByColumn;
	}
}

// 改变每页条数
function sizeChangeHandler() {
	console.log('sizeChangeHandler', formSubmitData);
	if (renderTableConfig.value.remote) {
		formSubmitData.value.pageNum = renderTableConfig.value.pagination?.pageNum;
		formSubmitData.value.pageSize = renderTableConfig.value.pagination?.pageSize;
		// 判断改变每页条数后是否会使当前页码发生改变，如果会，则不发起请求，由改变页码事件请求副本数据
		if (
			formSubmitData.value.pageNum !== undefined &&
			formSubmitData.value.pageNum > Math.ceil(localTotal.value / (formSubmitData.value.pageSize as number))
		) {
			return;
		}
		renderTableConfig.value.loading = true;
		renderTableConfig.value.remote(formSubmitData.value).then((res) => {
			renderTableConfig.value.loading = false;
			localData.value = res.result.data;
			localTotal.value = res.result.total;
		});
	} else {
		// console.warn("table config loss url, query by custom.");
		console.log('sizechage');
		// changePagination();
		nextTick(() => {
			$emit('sizeChangeHandler');
		});
	}
}
// 改变页码
function currentChangeHandler() {
	console.log('currentChangeHandler', formSubmitData);
	if (renderTableConfig.value.remote) {
		formSubmitData.value.pageNum = renderTableConfig.value.pagination?.pageNum;
		formSubmitData.value.pageSize = renderTableConfig.value.pagination?.pageSize;
		renderTableConfig.value.loading = true;
		renderTableConfig.value.remote(formSubmitData.value).then((res) => {
			renderTableConfig.value.loading = false;
			localData.value = res.result.data;
			localTotal.value = res.result.total;
		});
	} else {
		console.warn('table config loss url, query by custom.');
		nextTick(() => {
			$emit('currentChangeHandler');
		});
	}
}
// 改变排序
function sortChangeHandler(o: any) {
	// formSubmitData.value.orderByColumn = o.prop;
	if (renderTableConfig.value.pagination) {
		renderTableConfig.value.pagination.orderByColumn = o.prop;
		if (o.order === 'ascending') {
			renderTableConfig.value.pagination.isAsc = 'asc';
		} else if (o.order === 'descending') {
			renderTableConfig.value.pagination.isAsc = 'desc';
		} else {
			// 取消排序时恢复默认排序

			renderTableConfig.value.pagination.isAsc = '';
			renderTableConfig.value.pagination.orderByColumn = '';
		}
		lastOrder.value = renderTableConfig.value.pagination.isAsc;
	}
	// debugger;

	// 记录上一次的升降序

	if (renderTableConfig.value.remote) {
		renderTableConfig.value.loading = true;
		renderTableConfig.value.remote(cloneFormData.value).then((res) => {
			renderTableConfig.value.loading = false;
			localData.value = res.result.data;
			localTotal.value = res.result.total;
		});
	} else {
		console.warn('table config loss url, query by custom.');
		nextTick(() => {
			$emit('sortChangeHandler');
		});
	}
}
// 展开/收缩行事件
function expandChangeHandler(row: TableOptionType, expendRows: any) {
	for (let i = 0; i < expendRows.length; i++) {
		if (expendRows[i] === row) {
			// 展开
			$emit('expandRowHandler', row);
			return;
		}
	}
	// 收缩
	$emit('contractRowHandler', row);
}
// 复选框事件
const selectionChangeHandler = (selects: any) => {
	single.value = selects.length !== 1;
	multiple.value = !selects.length;
	$emit('selectionChangeHandler', selects);
};
// 获取表格对象
const getTableRef = () => {
	return tableRef.value;
};

const toggleRowExpansion = (row: any, flag?: boolean) => {
	console.log('swf-------', tableRef.value);
	if (flag !== undefined) {
		tableRef.value?.toggleRowExpansion(row, flag);
	} else {
		tableRef.value?.toggleRowExpansion(row);
	}
};

// 单击行事件
const rowClickHandler = (row: any) => {
	if (!renderTableConfig.value.enableRadio && !renderTableConfig.value.rowClick) {
		return;
	}
	renderTableConfig.value.radioId = row.id;
	renderTableConfig.value.radioRow = JSON.parse(JSON.stringify(row));
	$emit('rowClickHandler', row);
};
//选中行
// const selectHandler = (selection, row) => {
// 	$emit('selectHandler', selection, row);
// };
// 用正则表达式实现对对象某个属性的html转码
const htmlEncodeByRegExpRowHandle = (row: any, prop: string) => {
	return htmlEncodeByRegExpRow(row, prop);
};
// 获取序号列的下标
const getIndex = (pagination: any, ind: number) => {
	if (pagination instanceof Object) {
		let pageSize = pagination.pageSize || 10;
		let pageNum = pagination.pageNum || 1;
		return (pageNum - 1) * pageSize + ind + 1;
	} else {
		return ind + 1;
	}
};

defineExpose({
	getTableRef,
	toggleRowExpansion,
});
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.expand-table-box {
	border: 1px solid #56698d;
}
.pagination-box {
	padding: 20px;
	display: flex;
	justify-content: flex-end;
}
:deep(.cell) {
	display: flex;
	align-items: center;
}
</style>
<style>
.style-split-yd-table .el-table__expand-icon {
	color: transparent !important;
}
</style>
